aspectj
AspectJ是静态代理的增强,所谓的静态代理就是AOP框架会在编译阶段生成AOP代理类,因此也称为编译时增强。
相比于动态代理,aspectJ有更好的性能,但是需要特定的编译器,编译之后生成的class相比于java的编译器生成的class,会添加代理相关的逻辑。
java的动态代理
proxy(Proxy)是java中的代理类,handler(InvocationHandler)中封装的是具体的代理逻辑,根据被代理类和handler创建的代理类proxy,跟被代理类一样实现了相同的接口,但是生成的代理类中在被代理类的基础上加了代理逻辑,所以java的动态代理要求被代理类实现某个接口。
被代理类
1 | //接口 |
处理器(InvocationHandler)
1 | //封装了实际的代理逻辑 |
生成代理对象(Proxy)
1 | public static void main(String[] args) { |
spring的aop
与AspectJ的静态代理不同,Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。
java的动态代理上面已经做了解释,下面介绍一下通过CGLIB实现动态代理。
CGLIB实现动态代理
如果被代理类没有实现接口,那么spring会通过CGLIB实现动态代理。除了这种情况,还可以手动设置通过CGLIB实现动态代理:
1 | //官网说明 |
CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。